package com.qx.cn.dao;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

@Repository
@SuppressWarnings({"unchecked", "rawtypes"})
public class BaseDAOImpl extends HibernateDaoSupport implements BaseDAO
{
    @Autowired
    HibernateTemplate hibernateTemplate;
    
    @Override
    public Long count(Class clazz)
    {
        String countHql = "select count(*) from " + clazz.getSimpleName();
        return countByHql(countHql);
    }
    
    @Override
    public Long countByHql(String countHql, Object... args)
    {
        Long count = (Long)getHibernateTemplate().execute(new HibernateCallback()
        {
            @Override
            public Object doInHibernate(Session session)
            {
                Query query = session.createQuery(countHql);
                if ((args != null) && (args.length > 0))
                {
                    for (int i = 0; i < args.length; i++)
                    {
                        query.setParameter(i, args[i]);
                    }
                }
                Object object = query.setMaxResults(1).uniqueResult();
                return Long.parseLong(object.toString());
            }
        });
        return count;
    }
    
    @Override
    public Integer deleteByHql(String hql, Object... args)
    {
        Integer count = (Integer)getHibernateTemplate().execute(new HibernateCallback()
        {
            @Override
            public Object doInHibernate(Session session)
            {
                Query query = session.createQuery(hql);
                if ((args != null) && (args.length > 0))
                {
                    for (int i = 0; i < args.length; i++)
                    {
                        query.setParameter(i, args[i]);
                    }
                }
                return query.executeUpdate();
            }
        });
        return count;
    }
    
    @Override
    public void deleteById(Class clazz, Serializable id)
    {
        getHibernateTemplate().delete(loadById(clazz, id));
    }
    
    @PostConstruct
    public void initHibernateTemplate()
    {
        super.setHibernateTemplate(hibernateTemplate);
    }
    
    @Override
    public Object loadByHql(String hql, Object... args)
    {
        Object object = getHibernateTemplate().execute(new HibernateCallback()
        {
            @Override
            public Object doInHibernate(Session session)
            {
                Query query = session.createQuery(hql);
                if ((args != null) && (args.length > 0))
                {
                    for (int i = 0; i < args.length; i++)
                    {
                        query.setParameter(i, args[i]);
                    }
                }
                return query.setMaxResults(1).uniqueResult();
            }
        });
        return object;
    }
    
    @Override
    public Object loadById(Class clazz, Serializable id)
    {
        return getHibernateTemplate().get(clazz, id);
    }
    
    @Override
    public List query(Class clazz)
    {
        String hql = "from " + clazz.getSimpleName() + " as a order by a.id desc";
        return query(hql);
    }
    
    @Override
    public List query(String hql, int pageNo, int rows, Object[] args)
    {
        List list = getHibernateTemplate().executeFind(new HibernateCallback()
        {
            @Override
            public Object doInHibernate(Session session)
            {
                Query query = session.createQuery(hql);
                query.setFirstResult((pageNo - 1) * rows);
                query.setMaxResults(rows);
                if ((args != null) && (args.length > 0))
                {
                    for (int i = 0; i < args.length; i++)
                    {
                        query.setParameter(i, args[i]);
                    }
                }
                return query.list();
            }
        });
        return list;
    }
    
    @Override
    public List query(String hql, Object... args)
    {
        List list = getHibernateTemplate().executeFind(new HibernateCallback()
        {
            @Override
            public Object doInHibernate(Session session)
            {
                Query query = session.createQuery(hql);
                if ((args != null) && (args.length > 0))
                {
                    for (int i = 0; i < args.length; i++)
                    {
                        query.setParameter(i, args[i]);
                    }
                }
                return query.list();
            }
        });
        return list;
    }
    
    @Override
    public List queryBySql(String sql, Object... args)
    {
        return getHibernateTemplate().executeFind(new HibernateCallback()
        {
            @Override
            public List doInHibernate(Session session)
            {
                SQLQuery query = session.createSQLQuery(sql);
                if ((args != null) && (args.length > 0))
                {
                    for (int i = 0; i < args.length; i++)
                    {
                        query.setParameter(i, args[i]);
                    }
                }
                return query.list();
            }
        });
    }
    
    @Override
    public void saveOrUpdate(Object obj)
    {
        getHibernateTemplate().saveOrUpdate(obj);
    }
    
    @Override
    public Integer update(String hql, Object... args)
    {
        Integer count = (Integer)getHibernateTemplate().execute(new HibernateCallback()
        {
            @Override
            public Integer doInHibernate(Session session)
            {
                Query query = session.createQuery(hql);
                if ((args != null) && (args.length > 0))
                {
                    for (int i = 0; i < args.length; i++)
                    {
                        query.setParameter(i, args[i]);
                    }
                }
                return query.executeUpdate();
            }
        });
        return count;
    }
}